#pragma once

#include "../log.h"

namespace sfc::test {

auto _install(Str name, void (*func)()) -> usize;

template <class T>
auto install(void (*func)()) -> int {
#if defined(__clang__)
  static auto n1 = sizeof("int sfc::test::install(void (*)()) [T = ") - 1;
  static auto n2 = sizeof("]") - 1;
#elif defined(__GNUC__)
  static auto n1 = sizeof("int sfc::test::install(void (*)()) [with T = ") - 1;
  static auto n2 = sizeof("]") - 1;
#endif
  const auto p = __PRETTY_FUNCTION__;
  const auto n = sizeof(__PRETTY_FUNCTION__) - 1;
  return _install(Str{p + n1, n - n1 - n2}, func);
}

auto run(Str pattern) -> usize;

template <class, auto>
struct Fn {
  static const int INIT;
};

template <class T, auto F>
const int Fn<T, F>::INIT = test::install<T>(F);

}  // namespace sfc::test

#define sfc_test(T)                           \
  struct T {                                  \
    static void test();                       \
    ~T() {                                    \
      (void)sfc::test::Fn<T, &T::test>::INIT; \
    }                                         \
  };                                          \
  void T::test()
